package datamining.miner.enviroment;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import datamining.algorithms.prefixspan.PThreadEnvironment;
import datamining.miner.general.Fragment;
import datamining.miner.general.IntFrequency;
import datamining.miner.general.SequenceDataBase;
import datamining.sequence.HPSequence;
import datamining.sequence.ItemSet;
import datamining.sequence.Sequence;
import datamining.sequence.SequenceFactory;
import de.parsemis.graph.GraphFactory;
import de.parsemis.miner.environment.Statistics;
import settings.Settings;

/**
 * 创建于 2012-11-18 下午9:20:38
 * 
 * @author xujinghu (jinghuxu@nudt.edu.cn)
 * 
 *         Copyright 2012 xujinghu
 * 
 *         Lisence: Apache
 */
public class LocalEnvironment<ItemType> {

	private transient static LocalEnvironment environ;
	private SequenceDataBase db;
	private Collection<Fragment> returnSet = null;
	public final SequenceFactory factory;
	public final Statistics stats;

	private transient ThreadEnvironment<ItemType>[] threadEnvs;
	private int threadCount;
	private ThreadEnvironmentFactory tenvfac;
	public boolean storeEmbeddings = false;
	public boolean embeddingBased = false;
	public IntFrequency minFreq = new IntFrequency(1);
	public IntFrequency maxFreq = new IntFrequency(0);

	public static LocalEnvironment create(Settings settings, SequenceDataBase db, ThreadEnvironmentFactory envFac) {
		environ = new LocalEnvironment(settings,  db, envFac);
		return environ;
	}

	private LocalEnvironment(final Settings settings, SequenceDataBase db, ThreadEnvironmentFactory envFac){
		
		factory = settings.factory;
		this.db = db;
		threadCount = settings.threadCount;
		tenvfac = envFac;
		this.stats = settings.stats;
		this.minFreq = settings.minFreq;
		this.maxFreq = settings.maxFreq;
		this.embeddingBased = settings.embeddingBased;
		this.storeEmbeddings = settings.storeEmbeddings;
	}
	
	/**
	 * @author xujinghu
	 * @date 2012-12-2下午4:51:49
	 * @return 当前的环境
	 */
	public static LocalEnvironment env() {
		return environ;
	}

	public final Collection<Fragment> getReturnSet() {
		if (returnSet == null) {
			returnSet = new ArrayList<Fragment>();
		}
		return returnSet;
	}

	public ThreadEnvironment<ItemType> getThreadEnv(int idx) {
		// TODO Auto-generated method stub

		if (threadEnvs == null) {
			synchronized (this) {
				if (threadEnvs == null) {
					@SuppressWarnings("unchecked")
					final ThreadEnvironment<ItemType>[] t = new ThreadEnvironment[this.threadCount];
					threadEnvs = t;
				}
			}
		}
		synchronized (threadEnvs) {
			if (tenvfac == null) {
				return null;
			}
			if (threadEnvs[idx] == null) {
				final ThreadEnvironment<ItemType> tenv = tenvfac
						.getNewEnvironment(idx, this);
				threadEnvs[idx] = tenv;
				return tenv;
			} else {
				return threadEnvs[idx];
			}
		}

	}
	
	public <ItemType> Sequence<ItemType> newSequence(List<ItemSet<ItemType>> itemSets) {
		// TODO Auto-generated method stub
		return factory.newSequence(itemSets);
		
	}

	public Sequence<ItemType> newSequence() {
		// TODO Auto-generated method stub
		return factory.newSequence();
	}

}
